package com.frank.oj.controller.oj;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.frank.model.entity.judge.Judge;
import com.frank.oj.annotation.AnonApi;
import com.frank.oj.common.result.CommonResult;
import com.frank.oj.model.dto.SubmitIdListDTO;
import com.frank.oj.model.dto.SubmitJudgeDTO;
import com.frank.oj.model.dto.TestJudgeDTO;
import com.frank.oj.model.vo.JudgeCaseVO;
import com.frank.oj.model.vo.JudgeVO;
import com.frank.oj.model.vo.SubmissionInfoVO;
import com.frank.oj.model.vo.TestJudgeVO;
import com.frank.oj.service.oj.JudgeService;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;

/**
 * @author frank
 * @Date 2024/3/24
 */
@RestController
@RequestMapping("/api")
public class JudgeController {

    @Resource
    private JudgeService judgeService;

    /**
     * 获取提交列表
     *
     * @param limit             单页数
     * @param currentPage       当前页码
     * @param onlyMine          是否只获取自己的提交
     * @param searchPid         按题id搜索
     * @param searchStatus      按状态搜索
     * @param searchUsername    按用户名搜索
     * @param completeProblemID 是否获取完整题号
     * @param gid               团队id
     * @return 返回提交列表
     */
    @GetMapping("/get-submission-list")
    @AnonApi
    public CommonResult<IPage<JudgeVO>> getJudgeList(@RequestParam(value = "limit", required = false) Integer limit,
                                                     @RequestParam(value = "currentPage", required = false) Integer currentPage,
                                                     @RequestParam(value = "onlyMine", required = false) Boolean onlyMine,
                                                     @RequestParam(value = "problemID", required = false) String searchPid,
                                                     @RequestParam(value = "status", required = false) Integer searchStatus,
                                                     @RequestParam(value = "username", required = false) String searchUsername,
                                                     @RequestParam(value = "completeProblemID", defaultValue = "false") Boolean completeProblemID,
                                                     @RequestParam(value = "gid", required = false) Long gid) {

        return judgeService.getJudgeList(limit, currentPage, onlyMine, searchPid, searchStatus, searchUsername, completeProblemID, gid);
    }

    /**
     * 获取提交记录（单个）
     *
     * @param submitId 提交id
     * @return 返回提交记录
     */
    @GetMapping("/get-submission-detail")
    @AnonApi
    public CommonResult<SubmissionInfoVO> getSubmission(@RequestParam(value = "submitId", required = true) Long submitId) {
        return judgeService.getSubmission(submitId);
    }

    //############################################自 测#####################################################

    /**
     * 项目核心1：运行测试
     *
     * @param testJudgeDTO 测试数据
     * @return 测评信息
     */
    @PostMapping("/submit-problem-test-judge")
    @RequiresAuthentication
    @RequiresPermissions("submit")
    public CommonResult<String> submitProblemTestJudge(@RequestBody TestJudgeDTO testJudgeDTO) {
        return judgeService.submitProblemTestJudge(testJudgeDTO);
    }

    /**
     * 项目核心1：获取测试结果
     */
    @RequiresAuthentication
    @GetMapping("/get-test-judge-result")
    public CommonResult<TestJudgeVO> getTestJudgeResult(@RequestParam("testJudgeKey") String testJudgeKey) {
        return judgeService.getTestJudgeResult(testJudgeKey);
    }

    //##########################################提 交###################################################

    /**
     * 项目核心2：提交判题
     */
    @PostMapping("/submit-problem-judge")
    @RequiresAuthentication
    @RequiresPermissions("submit")
    public CommonResult<Judge> submitProblemJudge(@RequestBody SubmitJudgeDTO judgeDto) {
        return judgeService.submitProblemJudge(judgeDto);
    }

    /**
     * 对提交列表状态为Pending和Judging的提交进行更新检查
     */
    @PostMapping("/check-submissions-status")
    @AnonApi
    public CommonResult<HashMap<Long, Object>> checkCommonJudgeResult(@RequestBody SubmitIdListDTO submitIdListDto) {
        return judgeService.checkCommonJudgeResult(submitIdListDto);
    }

    /**
     * 需要检查是否为封榜，是否可以查询结果，避免有人恶意查询
     */
    @PostMapping("/check-contest-submissions-status")
    @RequiresAuthentication
    public CommonResult<HashMap<Long, Object>> checkContestJudgeResult(@RequestBody SubmitIdListDTO submitIdListDto) {
        return judgeService.checkContestJudgeResult(submitIdListDto);
    }


    /**
     * 调用判题服务器提交失败超过60s后，用户点击按钮重新提交判题进入的方法
     */
    @RequiresAuthentication
    @GetMapping(value = "/resubmit")
    public CommonResult<Judge> resubmit(@RequestParam("submitId") Long submitId) {
        return judgeService.resubmit(submitId);
    }

    /**
     * 获取指定提交的测试用例结果
     *
     * @param submitId 提交id
     * @return 测评信息
     */
    @GetMapping("get-all-case-result")
    @AnonApi
    public CommonResult<JudgeCaseVO> getAllCaseResult(@RequestParam(value = "submitId", required = true) Long submitId) {
        return judgeService.getAllCaseResult(submitId);
    }

    /**
     * 修改提交详情（分享权限）
     *
     * @param judge 判题信息
     * @return null
     */
    @PutMapping("/submission")
    @RequiresAuthentication
    public CommonResult<Void> updateSubmission(@RequestBody Judge judge) {
        return judgeService.updateSubmission(judge);
    }
}
